package logs

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var Log *zap.Logger

func Println(a ...any) {
	s := fmt.Sprint(a...)
	fmt.Println(time.Now().Format("15:04:05.000"), s)
	Log.Info(s)
}

func Printf(fmtStr string, a ...any) {
	s := fmt.Sprintf(fmtStr, a...)
	fmt.Println(time.Now().Format("15:04:05.000"), s)
	Log.Info(s)
}

// 方便输入
func Info(format string, a ...any) {
	s := fmt.Sprintf(format, a...)
	fmt.Println(time.Now().Format("15:04:05.000"), s)
	Log.Info(s)
}

// 方便输入，带 callstack 输出
func Warn(format string, a ...any) {
	s := fmt.Sprintf(format, a...)
	fmt.Println(time.Now().Format("15:04:05.000"), s)
	Log.Warn(s)
}

func InitDefaultLog(fileName string) {
	if fileName == "" {
		fileName = "./logs/zapTst.log"
	}
	// logger := initLogger()
	// logger.Info("Logger initialized")
	// logger.Error("This is an error message")
	// logger.Fatal("This is a fatal message", zap.Error(nil))

	// 这个函数重复创建也不会报错
	dir := filepath.Dir(fileName)
	// abs_dir, _ := filepath.Abs(dir)
	// fmt.Println("abs dir:", abs_dir)

	err := os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		panic(err)
	}

	cfg := zap.Config{
		Level:       zap.NewAtomicLevelAt(zap.DebugLevel),
		Development: true,
		Encoding:    "json",
		// OutputPaths: []string{"stdout", fileName},
		OutputPaths: []string{fileName}, // 不要控制台输出，有点乱
		EncoderConfig: zapcore.EncoderConfig{
			TimeKey:       "time",
			LevelKey:      "level",
			NameKey:       "logger",
			MessageKey:    "msg",
			StacktraceKey: "stack",
			LineEnding:    zapcore.DefaultLineEnding,
			EncodeLevel:   zapcore.LowercaseLevelEncoder,
			EncodeTime:    zapcore.ISO8601TimeEncoder,
		},
	}

	Log, err = cfg.Build(zap.AddStacktrace(zapcore.WarnLevel))
	if err != nil {
		panic(err)
	}
}

func InitLogger(fileName string) *zap.Logger {
	dir := filepath.Dir(fileName)

	err := os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		panic(err)
	}

	file, _ := os.Create(fileName)

	encoder := zapcore.NewJSONEncoder(zapcore.EncoderConfig{
		TimeKey:       "time",
		LevelKey:      "level",
		NameKey:       "logger",
		MessageKey:    "msg",
		StacktraceKey: "stack",
		LineEnding:    zapcore.DefaultLineEnding,
		EncodeLevel:   zapcore.LowercaseLevelEncoder,
		EncodeTime:    zapcore.ISO8601TimeEncoder,
	})

	core := zapcore.NewCore(
		encoder,
		zapcore.AddSync(file),
		zap.DebugLevel,
	)

	return zap.New(core)
}
